package config;

import java.util.ArrayList;
import java.util.List;

import org.svenson.JSON;
import org.svenson.JSONParser;

import controller.data.Comment;
import controller.data.ReadDocumentationRevision;
import controller.data.readDocumentation.ReadDocumentationResponse;
import controller.data.searchRevision.SearchRevisionResponse;
import controller.factorys.CommentFactory;
import controller.factorys.EditDocumentationRevisionFactory;
import controller.factorys.ReadDocumentResponseFactory;
import controller.factorys.ReadDocumentationRevisionFactory;
import controller.factorys.SearchRevisionFactory;

public class Parser {
	private final JSONParser parser;

	public Parser() {
		parser = new JSONParser();
		parser.addObjectFactory(new ReadDocumentResponseFactory());
		parser.addObjectFactory(new EditDocumentationRevisionFactory());
		parser.addObjectFactory(new ReadDocumentationRevisionFactory());
		parser.addObjectFactory(new CommentFactory());
		parser.addObjectFactory(new SearchRevisionFactory());
	}

	public List<Comment> parseCommentList(List<Object> objectList) {
		List<Comment> commentList = new ArrayList<Comment>();
		if (objectList != null) {
			for (Object o : objectList) {
				commentList.add(parseObjectToComment(o));
			}
		}
		return commentList;
	}

	private Comment parseObjectToComment(Object o) {
		String json = JSON.defaultJSON().forValue(o);
		return parser.parse(Comment.class, json);
	}

	public List<ReadDocumentationResponse> parseReadDocumentResponseList(
			String jsonResponse) {
		if (jsonResponse.startsWith("<")) {
			return new ArrayList<ReadDocumentationResponse>();
		}
		@SuppressWarnings("unchecked")
		List<Object> objectList = JSONParser.defaultJSONParser().parse(
				List.class, jsonResponse);
		List<ReadDocumentationResponse> readDocumentationResponseList = new ArrayList<ReadDocumentationResponse>();
		for (Object o : objectList) {
			readDocumentationResponseList
					.add(parseObjectToReadDocumentResponse(o));
		}
		return readDocumentationResponseList;
	}

	private ReadDocumentationResponse parseObjectToReadDocumentResponse(Object o) {
		String json = JSON.defaultJSON().forValue(o);
		return parser.parse(ReadDocumentationResponse.class, json);
	}

	public List<SearchRevisionResponse> parseSearchResponseList(
			String jsonResponse) {
		if (jsonResponse.startsWith("<")) {
			return new ArrayList<SearchRevisionResponse>();
		}

		List<SearchRevisionResponse> searchRevisionResponseList = new ArrayList<SearchRevisionResponse>();

		@SuppressWarnings("unchecked")
		List<Object> objectList = parser.parse(List.class, jsonResponse);

		for (Object o : objectList) {
			searchRevisionResponseList
					.add(parseObjectToSearchRevisionResponse(o));
		}
		return searchRevisionResponseList;
	}

	private SearchRevisionResponse parseObjectToSearchRevisionResponse(Object o) {
		String json = JSON.defaultJSON().forValue(o);

		SearchRevisionResponse searchRevisionResponse = parser.parse(
				SearchRevisionResponse.class, json);

		List<ReadDocumentationRevision> revisionList = new ArrayList<ReadDocumentationRevision>();
		for (Object object : searchRevisionResponse.getRevisions()) {
			revisionList.add(parseObjectToRevision(object));
		}
		searchRevisionResponse.setRevisions(revisionList);
		return searchRevisionResponse;
	}

	private ReadDocumentationRevision parseObjectToRevision(Object o) {
		String jsonString = JSON.defaultJSON().forValue(o);
		return parser.parse(ReadDocumentationRevision.class, jsonString);
	}
}
